热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

主轴|间距_八天让iOS开发者上手Flutter!

篇首语:本文由编程笔记#小编为大家整理,主要介绍了八天让iOS开发者上手Flutter!相关的知识,希望对你有一定的参考价值。Flutter布局

篇首语:本文由编程笔记#小编为大家整理,主要介绍了八天让iOS开发者上手Flutter!相关的知识,希望对你有一定的参考价值。



Flutter布局

Alignment

Container类里有一个alignment属性,翻译过来应该叫对齐方式,这个属性用来控制Container的子控件相对于它自身的一个位置。在我们ios开发中,我们知道坐标系的原点是在左上角。而在flutter中,坐标系的原点在父控件的正中心,可以使用这个alignment属性来控制子控件在父控件中的位置,它有两个参数分别是double类型的x,y。取值是-1到1,当0,0的时候表示子控件在父控件的正中心;当1,0的时候,表示子控件位于x方向上的最右侧,y方向上居中;当-1,-1的时候,表示子控件位于父控件的左上角位置。有点类似于CALayer的anchorPoint属性。如图代码如下:


Row

Row表示水平布局,它有一个children属性,用来存放它的子控件。代码如下:

其中Icon类是flutter提供的一个快速创建一些常用图标的类。如果想给每个Icon都加一个背景色,直接设置Icon的color是不行的,这样修改的是图标的颜色而不是背景色,给Icon包一层Container容器,然后再设置Container颜色这样就可以实现了。

最开始我们尝试了alignment属性的作用,当它是0,0的时候,Text的位置默认是在屏幕中央的。为什么这里换成我们的Row之后,Row的子控件位置不在屏幕中央呢?



首先作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS开发公众号:编程大鑫,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)



mainAxisAlignment

Row 和 Column 都有一个mainAxisAlignment属性,叫作主轴对齐方式,默认是MainAxisAlignment.start意思沿着主轴方向开始,Row布局下就是从左至右,Column布局下就是从上至下。
MainAxisAlignment.spaceAround:将剩下的空间平均分配
MainAxisAlignment.spaceBetween:将剩下的空间分配到子控件之间
MainAxisAlignment.spaceEvenly:等间距分配子控件


crossAxisAlignment

交叉轴对齐方式,start,end,center这几种方式试一下很好理解,stretch会将子控件拉伸。而baseline用的比较少,单独使用它会报错,需要和Text文本结合,还需要配合textBaseline属性一起使用。如下图所示,如果不设置CrossAxisAlignment.baselineTextBaseline.alphabetic就会根据控件高度水平对齐,而如果设置了就会根据控件内文本的基线对齐。


Column

这个和Row是对应的,Row是水平布局,这个Column是垂直布局

class LayoutDemo extends StatelessWidget
const LayoutDemo(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return Container(
color: Colors.green,
alignment: Alignment(0, 0),
child: Column(
children: [
Container(
child: Icon(Icons.add, size: 180,),
color: Colors.red,
),
Container(
child: Icon(Icons.ac_unit, size: 120,),
color: Colors.yellow,
),
Container(
child: Icon(Icons.access_alarm, size: 60,),
color: Colors.blue,
),
],
),
);


显示效果如图:


mainAxisAlignment

这个跟Row类似


crossAxisAlignment

这个跟Row类似


Stack

这个是用在Z轴上的布局的,row是X轴,column是Y轴。children数组第一个放在最底部,最后一个放在上面,离用户最近的地方。

class LayoutDemo extends StatelessWidget
const LayoutDemo(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return Container(
color: Colors.green,
alignment: Alignment(0, 0),
child: Stack(
children: [
Container(
child: Icon(Icons.add, size: 180,),
color: Colors.red,
),
Container(
child: Icon(Icons.ac_unit, size: 120,),
color: Colors.yellow,
),
Container(
child: Icon(Icons.access_alarm, size: 60,),
color: Colors.blue,
),
],
),
);


APP显示效果:


alignment

Stack里有一个alignment属性,它用来控制所有子控件相对于最大那个子控件的位置

class StackDemo extends StatelessWidget
const StackDemo(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return Stack(
alignment: Alignment.bottomRight,
children: [
Container(
child: Icon(Icons.add, size: 180,),
color: Colors.red,
),
Container(
child: Icon(Icons.ac_unit, size: 120,),
color: Colors.yellow,
),
Container(
child: Icon(Icons.access_alarm, size: 60,),
color: Colors.blue,
),
],
);



Positioned

Stack里配合Positioned类使用的话,跟我们iOS的约束有点类似了,可以设置上,左间距之类的

class StackDemo extends StatelessWidget
const StackDemo(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return Stack(
children: [
Positioned(
child: Container(
child: Icon(
Icons.add,
size: 180,
),
color: Colors.red,
),
),
Positioned(
child: Container(
child: Icon(
Icons.ac_unit,
size: 120,
),
color: Colors.yellow,
),
),
Positioned(
top: 20,
left: 20,
right: 20,
child: Container(
child: Icon(
Icons.access_alarm,
size: 60,
),
color: Colors.blue,
),
),
],
);

可以看到最小的蓝色视图的上左右均设置了20的间距,是不是熟悉的约束味道。。。


Expanded

Expanded是一个类似Container的常用的布局容器,它用来填充布局,使用了填充布局在主轴方向上是不会有间隔的,所以Expanded用在Row里面的时候,子控件的宽度设置就没有意义了,而在Column里面使用的使用,子控件的高度设置就没有意义了。这里以Column为例:

class LayoutDemo extends StatelessWidget
const LayoutDemo(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return Container(
color: Colors.green,
alignment: Alignment(0, 0),
child: Column(
children: [
Expanded(
child: Container(
child: Icon(Icons.add, size: 180,),
color: Colors.red,
),
),
Expanded(
child: Container(
child: Icon(Icons.ac_unit, size: 120,),
color: Colors.yellow,
),
),
Expanded(
child: Container(
child: Icon(Icons.access_alarm, size: 60,),
color: Colors.blue,
),
),
],
),
);



AspectRatio

AspectRatio是一个容器类,它有一个属性aspectRatio表示宽高比。如果指定了宽度,根据这个aspectRatio可以自动算出高度;如果指定了高度,根据aspectRatio可以自动算出宽度。如下面代码指定了父视图高度为100,aspectRatio宽高比为2,子视图宽度就是200,再把父视图撑起来也是200。

class LayoutDemo extends StatelessWidget
const LayoutDemo(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return Container(
color: Colors.green,
alignment: Alignment(0, 0),
child: Container(
color: Colors.blue,
height: 100,
child: AspectRatio(
aspectRatio: 2,
child: Icon(
Icons.add,
),
),
));


Flutter状态管理

之前介绍的这么多类都是无状态的,意思是显示之后没办法更新UI的,如果想要实时更新UI的话,就不能继承无状态的类了。我们先来看一个例子:明明count变化了,但是界面显示没有变化

记得修改APP的home视图

然后点击屏幕右下角的加号按钮,可以发现明明控制台打印了count的值已经发生了变化,但是界面显示依然是0

下面我们解决这个问题,将StateManagerDemo继承改为StatefulWidget,实现createState方法返回一个自定义的State对象,自定义的State对象里面实现build方法。还需要注意在按钮的点击方法里调用一下setState方法。这样每次点击加号按钮就能实时更新UI了。改造完之后如下图所示:


项目搭建之底部TabBar

到目前为止,我们对flutter的一些基础知识就算是介绍的差不多了。接下来我们开始做一个简单的仿微信APP。我们应该都有经验,理论的知识学得再多,不动手开始敲代码,不在项目中运用,是很难真正掌握一门知识的。

新建一个flutter工程,命名wechat_demo:

删掉多余的代码,可以全部重新自己写:

创建底部的TabBar和item,默认的type是白色的,显示效果很难看所以改为fixed,还可以设置fixedColor:

这样底部的TabBar就显示出来了,会发现点击没有效果,对比iOS会发现这块地方还是iOS提供的UITabBarController封装的更舒服,每个平台都各有优劣吧。

BottomNavigationBar有一个属性currentIndex即代表了当前选中的下标。我们可以通过设置它的值来控制哪个按钮被选中。既然需要改变UI了,说明我们需要将StatelessWidget改为StatefulWidget了。还有一个参数onTap是用来回调点击事件的。实现点击事件,切换currentIndex,重新setState就可以实现,点击切换了。我们将bottomNavigationBar相关代码放到一个新的文件rootPage中。代码如下:

记得修改main.dart文件中

这样就实现了APP的底部TabBar的展示,点击功能。点击每个item的时候,会发现flutter的bottomNavigationBar还自带了动画效果…

我们知道Scaffold还有一个body的属性,表示展示在屏幕上的内容。我们每个item对应的界面都需要一个AppBar,那么也许意味着,body属性还需要一个Scaffold来展示我们的每个item对应的内容。

可以看到微信首页就已经大概出来了,但是点击的时候只会显示这个微信页面,怎么实现切换不同的页面呢,肯定需要一个数组,来存放对应的每个页面了。

然后body里,根据我们的_currentIndex返回对应的body

这样点击每个item都会跳转到对应的界面了,APP的主框架的搭建好了。


总结

今天主要讲了flutter的三大布局类Row,Column,Stack以及他们的一些属性。然后是有状态的Widget和无状态的Widget,最后搭建了一下我们要做的仿微信APP的底部bottomNavigationBar和切换页面功能。


推荐阅读
  • Flutter 布局(四) Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth详解
    本文主要介绍Flutter布局中的Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth四种控件,详细介绍了其布局 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 标题: ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • C++语言入门:数组的基本知识和应用领域
    本文介绍了C++语言的基本知识和应用领域,包括C++语言与Python语言的区别、C++语言的结构化特点、关键字和控制语句的使用、运算符的种类和表达式的灵活性、各种数据类型的运算以及指针概念的引入。同时,还探讨了C++语言在代码效率方面的优势和与汇编语言的比较。对于想要学习C++语言的初学者来说,本文提供了一个简洁而全面的入门指南。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了响应式页面的概念和实现方式,包括针对不同终端制作特定页面和制作一个页面适应不同终端的显示。分析了两种实现方式的优缺点,提出了选择方案的建议。同时,对于响应式页面的需求和背景进行了讨论,解释了为什么需要响应式页面。 ... [详细]
  • macOS Big Sur全新设计大版本更新,10+个值得关注的新功能
    本文介绍了Apple发布的新一代操作系统macOS Big Sur,该系统采用全新的界面设计,包括图标、应用界面、程序坞和菜单栏等方面的变化。新系统还增加了通知中心、桌面小组件、强化的Safari浏览器以及隐私保护等多项功能。文章指出,macOS Big Sur的设计与iPadOS越来越接近,结合了去年iPadOS对鼠标的完善等功能。 ... [详细]
author-avatar
多米音乐_34026248
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有